/*
 * Copyright (c) 2018-2023 北京华恒盛世科技有限公司
 * QUICKPOOL is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
*/

#ifndef QUICKPOOL_LIB_H
#define QUICKPOOL_LIB_H

#include "limit.h"
#include "resreq.h"
#include "tclinfo.h"
#include "quickpool.h"

#define MAXARRAYJOBID     0x0FFFFFFFF
#define MAXARRAYINDEX     0x0FFFF

#define FATAL_ERR          -1
#define WARNING_ERR        -2

#define ARRAY_INDEX(jobId)                                            \
    (((jobId) == -1) ? (0) : (int)(((unsigned long long)jobId >> 32)       \
                                   & MAXARRAYINDEX))
#define ARRAY_JOBID(jobId)                                          \
    (((jobId) == -1) ? (-1) : (int)(jobId & MAXARRAYJOBID))

#define SET_STATE(s ,n) ((s) = ((s) & ~(MASK_QP_JOB_STATUS)) | (n))

#define LOAD_REASONS  (SUSPEND_REASON_LOADSTOP | SUSPEND_REASON_STOPCOND \
                       | SUSPEND_REASON_RESUMECOND | SUSPEND_REASON_NODEUNAVAIL)

#define MAX_JOB_IDS 100

#define USER_GRP          0x1
#define HOST_GRP          0x2
#define GRP_ALL           0x10

/* index for base parameters, used by quickpool daemons */
typedef enum {
    BASE_CONFDIR,
    BASE_SERVERDIR,
    BASE_LIBDIR,
    BASE_BINDIR,
    BASE_MASTER_LIST,
    BASE_EE_DEBUG,
    BASE_EE_PORT,
    BASE_EE_TIME_DEBUG,
    BASE_JM_DEBUG,
    BASE_JM_PORT,
    BASE_JM_TIME_DEBUG,
    BASE_JS_DEBUG,
    BASE_JS_PORT,
    BASE_JS_TIME_DEBUG,
    BASE_STRIP_DOMAIN,
    BASE_LOG_MASK,
    BASE_SERVER_HOSTS,
    BASE_AUTH,
    BASE_ID_PORT,
    BASE_API_CONNTIMEOUT,
    BASE_API_RECVTIMEOUT,
    BASE_AM_OPTIONS,
    BASE_TMPDIR,
    BASE_LOGDIR,
    NO_HOSTS_FILE,
    BASE_WORKDIR,
    BASE_SHAREDIR,
    OL_CGROUP_ROOT,
    QP_CHKPNT_ROOT,
    QP_CHKPNT_METHOD_DIR,
    QP_CHKPNT_METHOD,
    LICENSE_FILE,
    QP_CUDA_ENABLE,
    BASE_DEBUG_CMD,
    BASE_TIME_DEBUG_CMD,
    BASE_CMD_LOGDIR,
    BASE_CMD_LOGMASK,
    BASE_CONNECT_RETRY,
    CGROUP_MEMORY_ENFORCE,
} baseparams_t;

extern struct config_param baseParams[];

#define IDX_NOERR       0
#define IDX_BOUND       1
#define IDX_MEM         2
extern int idxerrno;

#define SACCT_GROUP    0x1
#define SACCT_USER     0x2
#define SACCT_USER_ALL 0x4

/* The share account structure which is on the
 * share tree representing each user and group.
 */
struct share_acct {
    char *name;       /* account name */
    unsigned int shares;  /* shares as configured */
    double dshares;   /* computed shares with siblings */
    unsigned int sent;    /* number of jobs to sent by this acct */
    unsigned int numPEND;      /* number of pending jobs */
    unsigned int numRUN;       /* number of running jobs */
    unsigned int numRAN;       /* number of jobs the account ran */
    unsigned int numBORROWED;  /* number of slots the account is borrowing */
    unsigned int deserve;    /* slot the account deserve based on ran */
    unsigned int options; /* SACCT_USER | SACCT_GROUP | SACCT_USER_ALL ... */
};

struct array_index {
    int start;
    int end;
    int step;
    struct array_index *next_index;
};

struct thresholds {
    unsigned int num_index;
    unsigned int num_threshold;
    float **load_stop;
    float **load_schedule;
};

struct usedCoreInfoDown {
    LIST_T *forw;
    LIST_T *back;    
    int parent_index;
    int pparent_index;
    int index_sibling;
    int index;
};

struct usedGpuIndex {
    LIST_T *forw;
    LIST_T *back;
    int gpu_index;
    int gpu_id;
    double alloc_mem;
};

struct nodeExecution {
    char *host_name;
    unsigned int num_slot;
    LIST_T *alloc_cores;
    LIST_T *alloc_gpus;
};

#define ACT_NO              0
#define ACT_START           1
#define ACT_DONE            3
#define ACT_FAIL            4

struct jobInfo {
    JOBID_T jobid;
    struct submitRequest *submit;
    int status;
    int	reasons;
    int	subreasons;
    pid_t job_pid;
    pid_t job_pgid;
    short nice;
    time_t start_time;
    unsigned int running;
    unsigned int number_node;
    struct nodeExecution *node_execinfo;
    membind_t membind_type;
    struct thresholds thresholds;
    int job_attribute;
    int signal;
    struct resourceLimit resource_limits[RESOURCE_LIMIT_NUM];
    char *run_window;
    LIST_T *run_winlist;
    pid_t restart_pid;
    unsigned int num_exec_files;
    struct execution_file *exec_files;
    int chkpnt_signal;
    pid_t act_pid;
    int mig;
    time_t suspend_time;
    char *prequeue_command;
    char *postqueue_command;
    float   lastCpuTime;
    unsigned int num_environment;
    char **environment;
    struct lenData eexec;
    char *requirement;
    char *prepost_user;
    char *execute_user;
    char *execute_cwd;
    char *execute_home;
    uid_t execute_uid;
    char *requeue_exitcode;
    char *resume_condition;
    char *stop_condition;
    char *suspend_command;
    char *resume_command;
    char *terminate_command;
    int quickpool_signal[QUICKPOOL_SIGNAL_NUMBER];
    int act_signal;
    char *schedule_host;
    struct lenData job_file;
    int gpu_exclusive;    
};

struct jmPackage {
    pid_t js_pid;
    unsigned int num_param;
    struct config_param *jm_params;
    unsigned int num_job;
    struct jobInfo *base_jobinfo;
    unsigned int num_admin;
    char **admins;
};

/* jobid.c */
extern void split_jobid(JOBID_T, int *, int *);
extern void combine_jobid(JOBID_T *, int, int);
extern bool_t issame_jobname(char *, char *);
extern void free_jobarray_idx(struct array_index *);
extern int get_jobids_fromstring(char *, JOBID_T **);
extern int get_jobid_indicies(char *, JOBID_T *, struct array_index **);
extern struct array_index *parse_jobname(char *, int *, int);
extern int parse_array_index(struct array_index **, int *);

/* jobusage.c */
extern void init_job_resourceusage(struct jobResourceUsage *);
extern void copy_job_resourceusage(struct jobResourceUsage *, struct jobResourceUsage *);
extern struct jobResourceUsage *dup_job_resourceusage(unsigned int, struct jobResourceUsage *);

/*xdr.c */
extern unsigned int sizeof_resource_reply(struct QuickPoolResourceReply *);
extern unsigned int sizeof_jobgroup_reply(struct QuickPoolJobGroupReply *);
extern unsigned int sizeof_groupinfo_reply(int, void *);
extern unsigned int sizeof_queueinfo_reply(struct QuickPoolQueueReply *, unsigned int);
extern unsigned int sizeof_quickpool_jobinfo(struct QuickPoolJobInfo *, unsigned int);

extern bool_t libxdr_submit_reply(XDR *, void *, struct header *, void *);
extern bool_t libxdr_jobinfo_submit(XDR *, void *, struct header *, void *);
extern bool_t libxdr_jobbase(XDR *, void *, struct header *, void *);
extern bool_t xdr_jm_package(XDR *, void *, struct header *, void *);
extern bool_t libxdr_thresholds(XDR *, void *, struct header *, void *);
extern bool_t xdr_file_data(XDR *, void *, struct header *, void *);
extern bool_t xdr_debug_setting(XDR *, void *, struct header *, void *);

extern bool_t libxdr_quickpoolinfo(XDR *, void *, struct header *, void *);
extern bool_t libxdr_setting(XDR *, void *, struct header *, void *);
extern bool_t libxdr_clusterinfo_reply(XDR *, void *, struct header *, void *);
extern bool_t libxdr_resource_reply(XDR *, void *, struct header *, void *);
extern bool_t libxdr_queue_reply(XDR *, void *, struct header *, void *);
extern bool_t libxdr_host_reply(XDR *, void *, struct header *, void *);
extern bool_t libxdr_load_reply(XDR *, void *, struct header *, void *);
extern bool_t libxdr_hostgroup_reply(XDR *, void *, struct header *, void *);
extern bool_t libxdr_usergroup_reply(XDR *, void *, struct header *, void *);
extern bool_t libxdr_user_reply(XDR *, void *, struct header *, void *);
extern bool_t libxdr_job_reply(XDR *, void *, struct header *, void *);
extern bool_t libxdr_jobinfo(XDR *, void *, struct header *, void *);
extern bool_t libxdr_jobgroup_reply(XDR *, void *, struct header *, void *);
extern bool_t libxdr_jobdep_reply(XDR *, void *, struct header *, void *);
extern bool_t libxdr_jobmsg_reply(XDR *, void *, struct header *, void *);
extern bool_t libxdr_peek_reply(XDR *, void *, struct header *, void *);
extern bool_t xdr_job_usage(XDR *, void *, struct header *, void *);
extern bool_t xdr_numainfo(XDR *, void *, struct header *, void *);
extern bool_t xdr_jobID(XDR *, void *, struct header *, void *);
extern bool_t libxdr_filecopy(XDR *, void *, struct header *, void *);
extern void free_job_usednuma(unsigned int, struct jobInfoNuma *);
extern void free_job_usedgpu(unsigned int, struct jobInfoGPU *);

/* subext.c */
extern int run_pipe(struct lenData *, char **, uid_t);
extern int run_exec(char *, JOBID_T, struct lenData *, char *);

/* resreq.c */
extern int initialize_parser_hash(struct quickpoolInfo *);
extern int set_requirement(char *, struct quickpoolInfo *, int, struct requirement *);
extern int merge_requirement_string(char **, char *);
extern void free_requirement(struct requirement *);
extern int get_resource_index_fromhash(const char *);

/* initparams.c */
extern int match_param_key(const char *, struct config_param *);
extern bool_t set_param_value(int, char *, struct config_param *);
extern void reset_param_value(struct config_param *);
extern void free_param_value(struct config_param *);

/* threshold.c */
extern bool_t check_resume_byload(JOBID_T, int, struct thresholds, struct QuickPoolHostInfo **, int *,
                                  int *, struct requirement *, struct Tcl_Node *,
                                  struct quickpoolInfo *);
extern void dup_thresholds(struct thresholds *, struct thresholds *);

#endif
